package scales.utils.collection
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentLinkedQueue
sealed trait Once[T] {
val value : T
}
trait ConcurrentMapUtils {
def getList[K, T](key: K, mapToList: ConcurrentHashMap[K, ConcurrentLinkedQueue[T]]): ConcurrentLinkedQueue[T] =
valueOf(key, mapToList)(
new ConcurrentLinkedQueue[T]())
def removeList[K, T](key: K, mapToList: ConcurrentHashMap[K, ConcurrentLinkedQueue[T]]): ConcurrentLinkedQueue[T] =
removeOr(key,mapToList)(new ConcurrentLinkedQueue[T]())
def removeOr[K, T](key: K, map: ConcurrentHashMap[K, T])(newT : => T): T = {
var res = map.remove(key)
if (res == null) {
res = newT
}
res
}
def calcOnce[K,T](key : K, map : ConcurrentHashMap[K, Once[T]])( calc : => T ) : T =
valueOf(key, map)(new Once[T]{
lazy val value = calc
}).
value
def valueOf[K,T](key : K, map : ConcurrentHashMap[K, T])( newT : => T ) : T = {
var value = map.get(key)
if (value == null) {
value = newT
val res = map.putIfAbsent(key, value)
value = if (res == null) value else res
}
value
}
}